//! 解析器和执行器错误类型

use thiserror::Error;

/// 解析错误
#[derive(Error, Debug)]
pub enum ParseError {
    #[error("语法错误: {message} at line {line}, column {column}")]
    SyntaxError {
        message: String,
        line: usize,
        column: usize,
    },
    
    #[error("词法错误: {message}")]
    LexicalError { message: String },
    
    #[error("语义错误: {message}")]
    SemanticError { message: String },
    
    #[error("不支持的语法: {feature}")]
    UnsupportedFeature { feature: String },
    
    #[error("解析器内部错误: {message}")]
    InternalError { message: String },

    #[error("执行错误: {0}")]
    ExecutionError(ExecutionError),

    #[error("其他错误: {message}")]
    Other { message: String },
}

/// 执行错误
#[derive(Error, Debug)]
pub enum ExecutionError {
    #[error("运行时错误: {message}")]
    RuntimeError { message: String },
    
    #[error("类型错误: {message}")]
    TypeError { message: String },
    
    #[error("变量未定义: {name}")]
    UndefinedVariable { name: String },
    
    #[error("函数未定义: {name}")]
    UndefinedFunction { name: String },
    
    #[error("参数错误: {message}")]
    ArgumentError { message: String },
    
    #[error("除零错误")]
    DivisionByZero,
    
    #[error("索引越界: {index}")]
    IndexOutOfBounds { index: usize },
    
    #[error("SQL执行错误: {message}")]
    SqlError { message: String },
    
    #[error("IO错误: {0}")]
    IoError(#[from] std::io::Error),
    
    #[error("序列化错误: {0}")]
    SerializationError(#[from] serde_json::Error),
    
    #[error("内核错误: {0}")]
    KernelError(#[from] data_gateway_kernel::KernelError),
}

/// 解析器结果类型
pub type Result<T> = std::result::Result<T, ParseError>;

impl ParseError {
    /// 创建语法错误
    pub fn syntax_error<S: Into<String>>(message: S, line: usize, column: usize) -> Self {
        Self::SyntaxError {
            message: message.into(),
            line,
            column,
        }
    }
    
    /// 创建词法错误
    pub fn lexical_error<S: Into<String>>(message: S) -> Self {
        Self::LexicalError {
            message: message.into(),
        }
    }
    
    /// 创建语义错误
    pub fn semantic_error<S: Into<String>>(message: S) -> Self {
        Self::SemanticError {
            message: message.into(),
        }
    }
    
    /// 创建不支持特性错误
    pub fn unsupported_feature<S: Into<String>>(feature: S) -> Self {
        Self::UnsupportedFeature {
            feature: feature.into(),
        }
    }
    
    /// 创建内部错误
    pub fn internal_error<S: Into<String>>(message: S) -> Self {
        Self::InternalError {
            message: message.into(),
        }
    }
}

impl ExecutionError {
    /// 创建运行时错误
    pub fn runtime_error<S: Into<String>>(message: S) -> Self {
        Self::RuntimeError {
            message: message.into(),
        }
    }
    
    /// 创建类型错误
    pub fn type_error<S: Into<String>>(message: S) -> Self {
        Self::TypeError {
            message: message.into(),
        }
    }
    
    /// 创建未定义变量错误
    pub fn undefined_variable<S: Into<String>>(name: S) -> Self {
        Self::UndefinedVariable {
            name: name.into(),
        }
    }
    
    /// 创建未定义函数错误
    pub fn undefined_function<S: Into<String>>(name: S) -> Self {
        Self::UndefinedFunction {
            name: name.into(),
        }
    }
    
    /// 创建参数错误
    pub fn argument_error<S: Into<String>>(message: S) -> Self {
        Self::ArgumentError {
            message: message.into(),
        }
    }
    
    /// 创建索引越界错误
    pub fn index_out_of_bounds(index: usize) -> Self {
        Self::IndexOutOfBounds { index }
    }
    
    /// 创建SQL错误
    pub fn sql_error<S: Into<String>>(message: S) -> Self {
        Self::SqlError {
            message: message.into(),
        }
    }
}

/// 错误位置信息
#[derive(Debug, Clone)]
pub struct ErrorLocation {
    pub line: usize,
    pub column: usize,
    pub offset: usize,
}

impl ErrorLocation {
    pub fn new(line: usize, column: usize, offset: usize) -> Self {
        Self { line, column, offset }
    }
}

/// 带位置信息的错误
#[derive(Debug)]
pub struct LocatedError {
    pub error: Box<dyn std::error::Error + Send + Sync>,
    pub location: Option<ErrorLocation>,
}

impl LocatedError {
    pub fn new(
        error: Box<dyn std::error::Error + Send + Sync>,
        location: Option<ErrorLocation>,
    ) -> Self {
        Self { error, location }
    }
}

impl std::fmt::Display for LocatedError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        if let Some(loc) = &self.location {
            write!(f, "{} at line {}, column {}", self.error, loc.line, loc.column)
        } else {
            write!(f, "{}", self.error)
        }
    }
}

impl std::error::Error for LocatedError {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        Some(self.error.as_ref())
    }
}

impl From<ExecutionError> for ParseError {
    fn from(err: ExecutionError) -> Self {
        ParseError::ExecutionError(err)
    }
}

impl From<anyhow::Error> for ParseError {
    fn from(err: anyhow::Error) -> Self {
        ParseError::Other { message: err.to_string() }
    }
}
